package sweet.config

import java.io._
/*
TODO: HashMap=>MutableHashMap ERROR???
import java.util.{ Properties, Hashtable=>JavaHashtable }
import scala.collection.jcl.{ Hashtable=>JclHashtable }
import scala.collection.mutable.{ HashMap=>MutableHashMap }
*/

import java.{ util=> jutil }
import scala.collection._

import sweet.helper.{ SProperties, JProperties, JSystem, StringHelper }
import StringHelper._

/* Config trait that is initializable and destroyable. */
trait Config { 
  def init: Unit = {}
  def destroy: Unit = {}  
}

/* Add abstract controller addProps. This trait will add props property. */
trait PropertiesConfig extends Config {
  val props = new mutable.HashMap[String,String]
  
  //abstract control to load properties from System.getProperties or System.getEnv. */
  def addProps(pairs: (String,String)*){
    props ++= pairs
  }
  
  //abstract control to load properties from file. */
  def addProps(file: File){
    val hash = new SProperties(JProperties(file))
    props ++= hash
  }
  
  /* abstract control to find a property from System.getProperties. If not found then
   * translate name from "." to "_" and tries to find it from System.getEnv. If still 
   * not found then return the default value. 
   * Note if ENV value is found, both the orig name and translated name will be inserted with 
   * it's value! */
  def addSysProps(name: String, default: String){
    JSystem.props.get(name) match {
      case Some(sv) => props += Pair(name, sv) //first case
      case None => {
        val envName = name.toUpperCase.fastReplace(".", "_")
        JSystem.env.get(envName) match {
          case Some(ev) => { //second case
            props += Pair(name, ev)
            props += Pair(envName, ev)
          }
          case None => props += Pair(name, default) //third case
        }
      }
    }    
  }
}

class MyConfig extends PropertiesConfig {
  addSysProps("myconfig.conf.file", "/tmp/test.properties")
  addProps(new File("/tmp/test2.properties"))  
  addProps(new File(props("moreConfigFile"))) //using properties
}

object ConfigDemo extends Application {
  val myconfig = new MyConfig
  myconfig.init
  println(myconfig.props)
  myconfig.destroy
}

